package rpc.remote.transport.socket;









import lombok.extern.slf4j.Slf4j;
import rpc.config.CustomShutDownHook;
import rpc.config.RpcServiceConfig;
import rpc.factory.SingletonFactory;
import rpc.provider.impl.ZkServiceProviderImpl;
import rpc.remote.dto.Message;
import rpc.provider.ServiceProvider;
import rpc.remote.transport.netty.server.NettyRpcServer;
import rpc.utils.concurrent.threadpool.ThreadPoolFactoryUtils;


import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;

/**
 * @ClassName: SocketRpcServer
 * @Description: 通信的服务端
 * @author: Kowk
 * @since:1.0.0
 */
@Slf4j
public class SocketRpcServer {
    //public static final Logger logger = LoggerFactory.getLogger(SocketRpcServer.class);

    //ExecutorService 会自动提供一个线程池和相关 API，用于为其分配任务。
    private ExecutorService threadPool;

    private final ServiceProvider serviceProvider;


    public SocketRpcServer(){
        threadPool = ThreadPoolFactoryUtils.createCustomThreadPoolIfAbsent("socket-server-rpc-pool");
        serviceProvider = SingletonFactory.getInstance(ZkServiceProviderImpl.class);
    }

    public void registerService(RpcServiceConfig rpcServiceConfig){
        serviceProvider.publishService(rpcServiceConfig);
    }



    public void start(int port){
        //创建socket并且绑定窗口
        try (ServerSocket server = new ServerSocket(port)){
            String host = InetAddress.getLocalHost().getHostAddress();
            server.bind(new InetSocketAddress(host, NettyRpcServer.PORT));
            CustomShutDownHook.getCustomShutDownHook().clearAll();
            Socket socket;
            //通过accept阻塞方法监听请求
            while ((socket = server.accept()) != null){
                log.info("client connected [{}]",socket.getInetAddress());
                threadPool.execute(new SocketRpcRequestHandlerRunnable(socket));
//                try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
//                     ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream())){
//                    //读取客户端输入流
//                    Message message = (Message) objectInputStream.readObject();
//                    log.info("client:"+message.getContent());
//                    message.setContent("Have been received");
//                    //响应客服端的信息
//                    objectOutputStream.writeObject(message);
//                    objectOutputStream.flush();
//                }
            }
            threadPool.shutdown();
        } catch (IOException e) {
            log.error("occur exception" + e);
        }
    }

}
